package com.gitee.feizns.webtemplate.commons.upload.processor;

import com.gitee.feizns.webtemplate.commons.upload.ImageConfigProperties;
import com.gitee.feizns.webtemplate.commons.upload.MediaType;
import com.gitee.feizns.webtemplate.commons.upload.UploadEvent;
import com.gitee.feizns.webtemplate.commons.upload.UploadProperties;
import com.gitee.feizns.webtemplate.commons.utils.StreamUtils;
import net.coobird.thumbnailator.Thumbnails;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

/**
 * 图片前置处理
 * @author feizns
 * @since 2019/5/15
 */
public class ImageBeforeProcessor extends DirHandler {

    public ImageBeforeProcessor(Processor processor) {
        super(MediaType.IMAGE, new ImageProcessorProxy(processor));
    }

    private static class ImageProcessorProxy implements Processor {

        private Processor processor;

        public ImageProcessorProxy(Processor processor) {
            this.processor = processor;
        }

        @Override
        public Map<MediaType, String[]> getProperty(UploadProperties uploadProperties) {
            return processor.getProperty(uploadProperties);
        }

        @Override
        public void write(UploadEvent event, String dir, UploadProperties properties) {
            ImageConfigProperties config = properties.getImageConfigProperties();

            try ( ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream() ) {

                Thumbnails.Builder<? extends InputStream> temp =
                        Thumbnails.of(event.getInputStream()).outputQuality(config.getQuality()).scale(config.getScale());

                //写入水印，（如果需要）
                if ( config.getMarkFile() != null ) {
                    try ( InputStream is =  new FileInputStream(config.getMarkFile()) ) {
                        BufferedImage image = Thumbnails.of(is).asBufferedImage();
                        temp = temp.watermark(config.getMarkPosition(), image, config.getMarkTransparent());
                    }
                }

                temp.toOutputStream(byteArrayOutputStream);

                try ( InputStream is = StreamUtils.copyStream(byteArrayOutputStream) ) {
                    UploadEvent.reset(event, is);
                    processor.write(event, dir, properties);
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }

}
